// Web Worker for image stitching
// This worker handles the CPU-intensive task of stitching images together

// Define types for messages
interface WorkerMessage {
  images: Array<{
    id: string;
    // url is not passed to worker as it can't be cloned
    name: string;
    width: number;
    height: number;
    format: string;
  }>;
  options: {
    arrangement: 'grid' | 'horizontal' | 'vertical';
    spacing: number;
    maxWidth: number;
    maxHeight: number;
    backgroundColor: string;
  };
}

interface ImagePosition {
  id: string;
  name: string;
  x: number;
  y: number;
  width: number;
  height: number;
  format: string;
}

/**
 * Calculate optimal grid dimensions for a given number of images
 * @param count Number of images
 * @returns [rows, columns]
 */
function calculateGridDimensions(count: number): [number, number] {
  const sqrt = Math.sqrt(count);
  const cols = Math.ceil(sqrt);
  const rows = Math.ceil(count / cols);
  return [rows, cols];
}

/**
 * Calculate dimensions and positions for stitched image
 * @param images Images to stitch
 * @param options Stitching options
 * @returns Object with width, height, and positions
 */
function calculateDimensions(
  images: WorkerMessage['images'],
  options: WorkerMessage['options']
): { width: number; height: number; positions: ImagePosition[] } {
  const { arrangement, spacing } = options;
  const positions: ImagePosition[] = [];
  
  let totalWidth = 0;
  let totalHeight = 0;
  
  if (arrangement === 'horizontal') {
    // All images in a row
    let currentX = 0;
    let maxHeight = 0;
    
    for (const image of images) {
      positions.push({
        id: image.id,
        name: image.name,
        x: currentX,
        y: 0,
        width: image.width,
        height: image.height,
        format: image.format
      });
      
      currentX += image.width + spacing;
      maxHeight = Math.max(maxHeight, image.height);
    }
    
    totalWidth = currentX - spacing; // Remove last spacing
    totalHeight = maxHeight;
  } else if (arrangement === 'vertical') {
    // All images in a column
    let currentY = 0;
    let maxWidth = 0;
    
    for (const image of images) {
      positions.push({
        id: image.id,
        name: image.name,
        x: 0,
        y: currentY,
        width: image.width,
        height: image.height,
        format: image.format
      });
      
      currentY += image.height + spacing;
      maxWidth = Math.max(maxWidth, image.width);
    }
    
    totalWidth = maxWidth;
    totalHeight = currentY - spacing; // Remove last spacing
  } else {
    // Grid arrangement
    const [_, cols] = calculateGridDimensions(images.length);
    
    let currentX = 0;
    let currentY = 0;
    let maxRowHeight = 0;
    let maxWidth = 0;
    
    for (let i = 0; i < images.length; i++) {
      const image = images[i];
      
      // If we've reached the end of a row, move to the next row
      if (i > 0 && i % cols === 0) {
        currentX = 0;
        currentY += maxRowHeight + spacing;
        maxRowHeight = 0;
      }
      
      positions.push({
        id: image.id,
        name: image.name,
        x: currentX,
        y: currentY,
        width: image.width,
        height: image.height,
        format: image.format
      });
      
      currentX += image.width + spacing;
      maxRowHeight = Math.max(maxRowHeight, image.height);
      maxWidth = Math.max(maxWidth, currentX - spacing);
    }
    
    totalWidth = maxWidth;
    totalHeight = currentY + maxRowHeight;
  }
  
  // Ensure dimensions don't exceed limits
  totalWidth = Math.min(totalWidth, options.maxWidth);
  totalHeight = Math.min(totalHeight, options.maxHeight);
  
  return { width: totalWidth, height: totalHeight, positions };
}

// Handle messages from the main thread
self.onmessage = async (e: MessageEvent<WorkerMessage>) => {
  const { images, options } = e.data;
  
  if (!images || images.length === 0) {
    self.postMessage({ 
      type: 'error', 
      data: { message: '没有图片可拼接' } 
    });
    return;
  }
  
  try {
    // Send initial progress
    self.postMessage({ type: 'progress', data: 0 });
    
    // Calculate dimensions and positions
    const { width, height, positions } = calculateDimensions(images, options);
    
    // Since we can't directly create and manipulate canvas in a worker,
    // we'll send the calculated positions back to the main thread
    // and let it handle the actual drawing
    
    // Send progress updates
    self.postMessage({ type: 'progress', data: 50 });
    
    // Simulate some processing time
    await new Promise(resolve => setTimeout(resolve, 500));
    
    // Send final result
    self.postMessage({
      type: 'complete',
      data: {
        width,
        height,
        positions,
        backgroundColor: options.backgroundColor
      }
    });
  } catch (error: any) {
    self.postMessage({ 
      type: 'error', 
      data: { message: error.message || '拼接过程中发生错误' } 
    });
  }
};